package com.zycfc.zsf.boot.util.time;

import org.apache.commons.lang3.time.*;
import java.util.concurrent.atomic.*;

public abstract class CachingDateFormatter
{
    private FastDateFormat fastDateFormat;
    private AtomicReference<CachedTime> cachedTime;
    private boolean onSecond;
    
    public CachingDateFormatter(final String pattern) {
        this(FastDateFormat.getInstance(pattern));
    }
    
    public CachingDateFormatter(final FastDateFormat fastDateFormat) {
        this.fastDateFormat = fastDateFormat;
        this.onSecond = (fastDateFormat.getPattern().indexOf("SSS") == -1);
        final long current = System.currentTimeMillis();
        this.cachedTime = new AtomicReference<CachedTime>(new CachedTime(current, fastDateFormat.format(current)));
    }
    
    public String format(final long timestampMillis) {
        CachedTime cached = this.cachedTime.get();
        final long timestamp = this.onSecond ? (timestampMillis / 1000L) : timestampMillis;
        if (timestamp != cached.timestamp) {
            final CachedTime newCachedTime = new CachedTime(timestamp, this.fastDateFormat.format(timestampMillis));
            if (this.cachedTime.compareAndSet(cached, newCachedTime)) {
                cached = newCachedTime;
            }
            else {
                cached = this.cachedTime.get();
            }
        }
        return cached.formatted;
    }
    
    static final class CachedTime
    {
        private long timestamp;
        private String formatted;
        
        public CachedTime(final long timestamp, final String formatted) {
            this.timestamp = timestamp;
            this.formatted = formatted;
        }
    }
}
